package de.Objects;

import javax.media.j3d.AmbientLight;
import javax.media.j3d.Appearance;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.DirectionalLight;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.Material;
import javax.media.j3d.PointLight;
import javax.media.j3d.Texture;
import javax.media.j3d.Texture2D;
import javax.media.j3d.TextureAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.vecmath.Color3f;
import javax.vecmath.Point3d;
import javax.vecmath.Vector3f;

import unbboolean.j3dbool.BooleanModeller;
import unbboolean.j3dbool.Solid;
import unbboolean.solids.CylinderSolid;

import com.sun.j3d.utils.geometry.Cylinder;
import com.sun.j3d.utils.geometry.Primitive;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.image.TextureLoader;

public class Housing extends BranchGroup {

	BranchGroup root = new BranchGroup();
	Appearance apper = new Appearance();
	Appearance apper2 = new Appearance();
	Appearance apper3 = new Appearance();

	public Housing() {

		addLight();

// //////// create Material
		Color3f ambient = new Color3f(0.0f, 0.0f, 0.0f);
		Color3f emissive = new Color3f(0.6f, 0.6f, 0.6f);
		Color3f diffuse = new Color3f(0.8f, 0.8f, 0.8f);
		Color3f specular = new Color3f(0.5f, 0.5f, 0.5f);
		Material material = new Material(ambient, emissive, diffuse, specular,
				100.0f);
		material.setLightingEnable(true);
		TextureLoader loaderBase = new TextureLoader("textures/snow1G.jpg",
				TextureLoader.GENERATE_MIPMAP, null);
		ImageComponent2D imageBase = loaderBase.getImage();

		int imageBaseWidth = imageBase.getWidth();
		int imageBaseHeigth = imageBase.getHeight();

		Texture2D textTureBase = new Texture2D(Texture.MULTI_LEVEL_MIPMAP,
				TextureLoader.GENERATE_MIPMAP, imageBaseWidth, imageBaseHeigth);
		int imagelevelBase = 0;
		textTureBase.setImage(imagelevelBase, imageBase);

		while (imageBaseWidth > 1 || imageBaseHeigth > 1) {
			imagelevelBase++;
			if (imageBaseWidth > 1) {
				imageBaseWidth /= 2;
			}
			if (imageBaseHeigth > 1) {
				imageBaseHeigth /= 2;
			}
			imageBase = loaderBase.getScaledImage(imageBaseWidth,
					imageBaseHeigth);
			textTureBase.setImage(imagelevelBase, imageBase);
		}
		textTureBase.setMagFilter(Texture.BASE_LEVEL_POINT);
		textTureBase.setMinFilter(Texture.MULTI_LEVEL_POINT);
		TextureAttributes texAttrBase = new TextureAttributes();
		texAttrBase.setTextureMode(TextureAttributes.MODULATE);

		apper.setTexture(textTureBase);
		apper2.setTextureAttributes(texAttrBase);
		apper2.setTexture(textTureBase);
		apper2.setMaterial(material);
		apper3.setTextureAttributes(texAttrBase);
		apper3.setTexture(textTureBase);
		apper3.setMaterial(material);

// ///////Create non shining Floor

		Cylinder floor = new Cylinder(50.0f, 1.0f,
				Primitive.GENERATE_NORMALS_INWARD
						| Primitive.GENERATE_TEXTURE_COORDS, 100, 100, apper3);
		Transform3D translationFloor = new Transform3D();
		translationFloor.setTranslation(new Vector3f(0.0f, -9.0f, 0.0f));
		TransformGroup tgFloor = new TransformGroup(translationFloor);
		root.addChild(tgFloor);
		tgFloor.addChild(floor);

// ////////Create The Iglu Inside

		Transform3D rotationY = new Transform3D();
		rotationY.rotZ(Math.PI / 2.0);
		Transform3D translationIglu = new Transform3D();
		translationIglu.mul(rotationY);
		translationIglu.setTranslation(new Vector3f(0.0f, -10.0f, 0.0f));
		TransformGroup tgIglu = new TransformGroup(translationIglu);
		root.addChild(tgIglu);

		Sphere sp1 = new Sphere(50.0f, Primitive.GENERATE_NORMALS_INWARD
				| Primitive.GENERATE_TEXTURE_COORDS, 100, apper);
		tgIglu.addChild(sp1);

// ////////Create The Iglu outside

		Sphere sp2 = new Sphere(51.0f, Primitive.GENERATE_NORMALS
				| Primitive.GENERATE_TEXTURE_COORDS, 100, apper2);
		tgIglu.addChild(sp2);

// //////Solid Cylinder with boolean operation
		Transform3D rotationX = new Transform3D();
		rotationX.rotX(Math.PI / 2.0);
		Transform3D translationExit = new Transform3D();
		translationExit.mul(rotationX);
		translationExit.setTranslation(new Vector3f(0.0f, -9.0f, 52.0f));
		TransformGroup tgExit = new TransformGroup(translationExit);

		root.addChild(tgExit);
		CylinderSolid CS1 = new CylinderSolid("CS", 14.5f, 20.5f, 20.5f,
				new Color3f(1f, 1f, 1f));
		CylinderSolid CS2 = new CylinderSolid("CS", 14.5f, 17.5f, 17.5f,
				new Color3f(1f, 1f, 1f));
		BooleanModeller m = new BooleanModeller(CS1, CS2);
		Solid b = new Solid();
		b = m.getDifference();
		tgExit.addChild(b);

		super.addChild(root);
	}

	public void addLight() {
		// Ein AmbientLight wird erzeugt
		AmbientLight lightA = new AmbientLight();
		lightA.setInfluencingBounds(new BoundingSphere(new Point3d(0.0f, 0.0f,
				0.0f), 100.0f));
		lightA.setColor(new Color3f(1f, 1f, 1f));
		lightA.setEnable(true);
		root.addChild(lightA);

		// Ein DirectionalLight wird erzeut -> strahlt von Links
		DirectionalLight lightD1 = new DirectionalLight();
		lightD1.setInfluencingBounds(new BoundingSphere(new Point3d(0.0f, 0.0f,
				0.0f), 100.0f));
		lightD1.setColor(new Color3f(1.0f, 0.0f, 0.0f));
		lightD1.setDirection(new Vector3f(0.0f, 0.0f, 0.0f));
		lightD1.setEnable(true);
		root.addChild(lightD1);

		// Ein PointLight wird erzeugt
		PointLight lightP1 = new PointLight();
		lightP1.setColor(new Color3f(1.0f, 1.0f, 1.0f));
		lightP1.setPosition(0.0f, 100.0f, 0.0f);
		lightP1.setInfluencingBounds(new BoundingSphere(new Point3d(0.0f, 0.0f,
				0.0f), 100.0f));
		root.addChild(lightP1);
	}
}